﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using PlanningGIS.ManageUtility.DataAccess;
using PlanningGIS.Util.Log;

namespace PlanningGIS.ManageUtility.Modules
{
    /// <summary>
    /// 用户界面模型对象
    /// </summary>
    public class User : UserInfo
    {
        /// <summary>
        /// 获取或设置用户所能操作的功能权限
        /// </summary>
        public List<IPrivilegeGroup> MenuContents { get; set; }

        /// <summary>
        /// 获取或设置用户所能操作的TOC权限
        /// </summary>
        public List<IPrivilegeGroup> TocContents { get; set; }

        /// <summary>
        /// 获取或设置用户的范围权限
        /// </summary>
        public List<string> UserRegions { get; set; }

        /// <summary>
        /// 获取或设置用户所属的角色
        /// </summary>
        public List<string> UserRoles { get; set; }

        /// <summary>
        /// 获取或设置用户有权限的资源、模板、功能等关联信息
        /// </summary>
        public List<Role_Rel> UserRels { get; set; }

        /// <summary>
        /// 获取或设置用户有权限的资源、模板、功能等关联信息
        /// </summary>
        public DataTable RoleRelTable { get; set; }

        /// <summary>
        /// 本地功能权限配置文件
        /// </summary>
        public string LocalMenuPrivile { get; set; }

        /// <summary>
        /// 本地图层权限配置文件
        /// </summary>
        public string LocalTocPrivile { get; set; }

        /// <summary>
        /// 系统消息
        /// </summary>
        public string Message { get; protected set; }

        /// <summary>
        /// 从UserInfo对象复制用户信息
        /// </summary>
        /// <param name="user"></param>
        public void Parse(UserInfo user)
        {
            if (user == null) return;
            //this.ID = user.ID;
            //this.Login_Name = user.Login_Name;
            //this.PSD = user.PSD;
            //this.Name = user.Name;
            //this.DepartMent_ID = user.DepartMent_ID;

            PropertyInfo[] thisPIs = this.GetType().GetProperties();
            PropertyInfo[] otherPIs = user.GetType().GetProperties();
            foreach (PropertyInfo pi in thisPIs)
            {
                if (!pi.CanWrite) continue;
                string name = pi.Name;
                PropertyInfo opi = otherPIs.FirstOrDefault(t => t.Name.Equals(pi.Name, StringComparison.CurrentCultureIgnoreCase));
                if (opi == null || !opi.CanRead) continue;
                pi.SetValue(this, opi.GetValue(user, null), null);
            }


        }

        /// <summary>
        /// 初始化用户数据
        /// </summary>
        public bool InitData()
        {
            try
            {
                if (!IsAdministrator())
                {
                    if (GetUserInfo())
                    {
                        MenuContents = GetPrivile(ManageHelper.KEY_FUNCTION);
                        TocContents = GetPrivile(ManageHelper.KEY_TOC);
                    }
                }
                else
                {

                    return ReadPrivile();
                }
                return true;
            }
            catch (Exception ex)
            {
                Message = ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 读取本地功能权限
        /// </summary>
        /// <returns></returns>
        protected bool ReadPrivile()
        {
            if (string.IsNullOrWhiteSpace(LocalMenuPrivile) || !System.IO.File.Exists(LocalMenuPrivile))
            {
                Message = "系统功能配置文件【" + LocalMenuPrivile + "】文件不存在！";
                //System.Diagnostics.Process.GetCurrentProcess().Kill();
                return false;
            }
            if (string.IsNullOrWhiteSpace(LocalTocPrivile) || !System.IO.File.Exists(LocalTocPrivile))
            {
                Message = "系统图层配置文件【" + LocalTocPrivile + "】文件不存在！";
                //System.Diagnostics.Process.GetCurrentProcess().Kill();
                return false;
            }
            XmlDocument doc = new XmlDocument();
            doc.Load(LocalMenuPrivile);
            PrivilegeGroup rolecontent = new PrivilegeGroup();
            rolecontent.Xml = doc.InnerXml;
            List<IPrivilegeGroup> group = new List<IPrivilegeGroup>();
            foreach (IPrivilegeElement element in rolecontent.GetChilds())
            {
                if (element is IPrivilegeGroup)
                {
                    group.Add(element as IPrivilegeGroup);
                }
            }
            MenuContents = group;

            doc = new XmlDocument();
            doc.Load(LocalTocPrivile);
            rolecontent = new PrivilegeGroup();
            rolecontent.Xml = doc.InnerXml;
            List<IPrivilegeGroup> tocMenugroup = new List<IPrivilegeGroup>();
            foreach (IPrivilegeElement element in rolecontent.GetChilds())
            {
                if (element is IPrivilegeGroup)
                {
                    tocMenugroup.Add(element as IPrivilegeGroup);
                }
            }
            TocContents = tocMenugroup;
            return true;
        }

        /// <summary>
        /// 获取用户权限信息
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private List<IPrivilegeGroup> GetPrivile(string key)
        {
            try
            {
                Hash_Table ht = ManageHelper.GetHash_Table(key);
                if (ht == null || ht.Value == null || ht.Value.Length == 0) return null;
                PrivilegeGroup funcGroup = new PrivilegeGroup();
                funcGroup.Xml = Encoding.UTF8.GetString(ht.Value);
                List<IPrivilegeElement> groups = funcGroup.GetChilds();
                if (groups == null || groups.Count == 0) return null;
                if (!IsAdministrator())
                {
                    SetPrivileEnable(groups);
                }
                List<IPrivilegeGroup> _privilege = new List<IPrivilegeGroup>();
                foreach (IPrivilegeGroup group in groups)
                {
                    _privilege.Add(group as IPrivilegeGroup);
                }
                return _privilege;
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog(ex.Message);
                return null;
            }
        }

        /// <summary>
        /// 添加权限
        /// </summary>
        /// <param name="item"></param>
        /// <param name="parentNode"></param>
        private void SetPrivileEnable(List<IPrivilegeElement> groups)
        {
            foreach (IPrivilegeElement item in groups)
            {
                if (!item.Enable) continue;
                string tmp = item.GetKeyName();
                if (!ExistsKey(item.GetKeyName()))
                {
                    item.Enable = false;
                    continue;
                }
                if (item is IPrivilegeGroup)
                {
                    SetPrivileEnable(((IPrivilegeGroup)item).GetChilds());
                }
            }
        }

        /// <summary>
        /// 是否存在指定的功能权限键值
        /// </summary>
        /// <param name="keyname"></param>
        /// <returns></returns>
        private bool ExistsKey(string keyname)
        {
            if (RoleRelTable == null || RoleRelTable.Rows.Count == 0) return false;
            DataRow[] drs = RoleRelTable.Select("relid = '" + keyname + "'");
            if (drs == null || drs.Length == 0) return false;
            return true;
        }

        /// <summary>
        /// 获取用户权限、角色、范围权限等信息
        /// </summary>
        /// <returns></returns>
        private bool GetUserInfo()
        {
            try
            {
                RoleRelTable = UserAccess.GetUserRel(ID);
                DataTable dt = UserAccess.GetUserRole(ID);
                if (dt == null || dt.Rows.Count == 0)
                {
                    Message = "该用户没有使用系统功能的权限，请联系管理员！";
                    return false;
                }
                UserRoles = new List<string>();
                UserRegions = new List<string>();
                foreach (DataRow dr in dt.Rows)
                {
                    object obj = dr["rolename"];
                    string rolename = obj == null ? "" : obj.ToString();
                    UserRoles.Add(rolename);

                    if (dr["extent_right"] != null && dr["extent_right"] != DBNull.Value)
                    {
                        string extent = Encoding.UTF8.GetString((byte[])dr["extent_right"]);
                        if (!string.IsNullOrWhiteSpace(extent))
                        {
                            string[] es = extent.Split(',');
                            foreach (string s in es)
                            {
                                if (!UserRegions.Contains(s))
                                {
                                    UserRegions.Add(s);
                                }
                            }
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Message = ex.Message;
                return false;
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private List<Role_Rel> GetUserRel()
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<MXDInfo> GetMxdInfos()
        {
            List<MXDInfo> mxds = ManageHelper.DBContext.GetAllEntry<MXDInfo>();
            if (mxds == null || mxds.Count == 0) return null;            
            List<MXDInfo> newmxds = mxds.FindAll(new Predicate<MXDInfo>(delegate(MXDInfo m)
            {
                if (IsAdministrator()) return true;
                if (RoleRelTable == null || RoleRelTable.Rows.Count == 0) return false;
                if (!m.GetEnable()) return false;
                DataRow[] drs = RoleRelTable.Select(string.Format("relid = '{0}'", m.ID));
                if (drs == null || drs.Length == 0) return false;
                return true;
            }));
            return newmxds;
        }

    }

}
